import threading
from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse, StreamingHttpResponse
import os
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from .models import InformationBox, GraphService, PHQ9Load
from .forms import *
from .tools import tool, ToolPdf, provinceItem, PHQ9, aiResponse
import random
import json
import time

ProvinceLoader = provinceItem.Tools()
ProvinceLoader.InitSettings()

phq9 = PHQ9.Tools()
ColumnAi = aiResponse.columnAi()


# 修饰器
def GetEmail(func):
    def warpper(request):
        name = None
        if request.method == "POST":
            name = request.POST.get("InputEmail", "None")
        load = func(request, name)
        return load

    return warpper


def UpdateInfo(request, username):
    Items = tool.GraphTool()
    UserItem = User.objects.get(username=username)
    if Items:
        for _ in Items:
            if _['username'] == username:
                try:
                    graphItem = GraphService.objects.get(user=UserItem, name=_['name'])
                    graphItem.radar_data = _['radarSize']
                    graphItem.radar_labels = _['radarLabels']
                    graphItem.pie_data = _['pieSize']
                    graphItem.pie_labels = _['pieLabels']
                    graphItem.save()
                except GraphService.DoesNotExist:
                    graph_service = GraphService(
                        user=UserItem,  # 确保这里传入的是User实例
                        name=_['name'],
                        radar_data=_['radarSize'],
                        radar_labels=_['radarLabels'],
                        pie_data=_['pieSize'],
                        pie_labels=_['pieLabels'],
                    )
                    graph_service.save()


# 页面函数
def LoadName(request):
    # 验证是否登录
    if request.user.is_authenticated:
        username = request.user.username
    else:
        username = None
    return username


def LogoutInfo(request):
    logout(request)
    return redirect('index')


def LoginInfo(request):
    page_name = 'login.html'
    context = {}
    height = 400
    if request.method == 'POST':
        # 登录表格
        form = LoginForm(data=request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            user = authenticate(request, username=username, password=password)
            if user is not None:

                # 登录成功
                try:
                    run_tool = threading.Thread(target=UpdateInfo, args=(request, username))
                    run_tool.start()
                finally:
                    pass
                login(request, user)
                return redirect('index')
            else:
                height = 600
                form.add_error(None, '用户名或密码错误')
    else:
        form = LoginForm()
    context['height'] = height
    context['form'] = form
    return render(request, template_name=page_name, context=context)


@GetEmail
def LodeInformation(request, name):
    page_name = 'information.html'
    username = LoadName(request)
    context = {}
    Information = InformationBox.objects.filter(RxUser=username)
    usersInformation = [[i + 1, Information[i]] for i in range(len(Information))]

    now = usersInformation[0][1].id
    if request.method == "GET":
        now = request.GET.get("Now", usersInformation[0][1].id)

    url = InformationBox.objects.get(id=now).url

    context['url'] = url
    context['Now'] = now
    context['username'] = username
    context['usersInformation'] = usersInformation
    page = render(request, template_name=page_name, context=context)

    return page


@GetEmail
def IndexInfo(request, name):
    # 初始页面函数
    page_name = "index.html"
    context = {}
    username = LoadName(request)
    context['username'] = username
    page = render(request, template_name=page_name, context=context)
    return page


def ServiceInfo(request):
    # 服务页面函数
    page_name = "service-details.html"
    context = {}

    if request.user.is_authenticated:
        name = request.user.username
    else:
        name = "admin"

    pos = 'pieChart'
    if request.method == "GET":
        pos = request.GET.get("pos", 'pieChart')

    try:
        userItem = User.objects.get(username=name)
        userdata = userItem.AnalyseData.all()
        logs = {}
        TheFirstUser = userdata[0].name
        names = []

        for _ in userdata:
            id = _.id
            name = _.name
            names.append(name)
            radar_data = _.radar_data
            radar_labels = _.radar_labels
            pie_data = _.pie_data
            pie_labels = _.pie_labels
            logs[name] = {
                'id': id,
                'radar_data': radar_data,
                'radar_labels': radar_labels,
                'pie_data': pie_data,
                'pie_labels': pie_labels,
            }

        AnalyseName = TheFirstUser
        if request.method == "GET":
            pos = request.GET.get("pos", 'chatBot')
            AnalyseName = request.GET.get("name", TheFirstUser)

        item = logs[AnalyseName]

        if pos == 'pieChart':
            context['labels'] = item['pie_labels']
            context['data'] = item['pie_data']
            context['colors'] = [
                f'rgb({random.randint(100, 125)},{random.randint(200, 225)},{random.randint(125, 255)})'
                for _ in range(len(item['pie_data']))]
            page_name = 'service-pie.html'

        elif pos == 'barChart':
            context['labels'] = item['radar_labels']
            context['data'] = item['radar_data']
            context['colors'] = [
                f'rgb({random.randint(100, 125)},{random.randint(200, 225)},{random.randint(125, 255)})'
                for _ in range(len(item['radar_data']))]
            page_name = 'service-bar.html'

        elif pos == 'chatBot':
            page_name = 'service-chat.html'

        context['Graph'] = '#' + pos
        context['Analyse'] = AnalyseName
        context['names'] = names

    except IndexError:
        errorInfo = "目前您还没有做过测试哦，数据暂无"
        context['lack'] = errorInfo

    context['pos'] = pos
    context['items'] = ['chatBot', 'pieChart', 'barChart']
    context['username'] = name
    page = render(request, template_name=page_name, context=context)
    return page


def FastUrl(requset):
    # 测试用跳转界面
    return redirect("index")


@login_required(login_url='login')
def Test(request):
    username = LoadName(request)
    context = {}
    page_name = "test.html"
    userItem = User.objects.get(username=username)
    userdata = userItem.AnalyseData.all()

    testdata = userdata[0]
    piedata = list(map(int, testdata.pie_data))
    pielabel = testdata.pie_labels

    context['piedata'] = piedata
    context['pielabel'] = pielabel
    context['username'] = username

    page = render(request, page_name, context)
    return page


def ChatInfo(request):
    page_name = 'chat.html'
    context = {}
    page = render(request=request, template_name=page_name, context=context)
    return page


def CreatePdf(request, name):
    items = GraphService.objects.get(name=name)
    analyse_data = items.pie_data
    analyse_labels = items.pie_labels
    question = ["test" for _ in range(len(analyse_data))]
    advice = [["Test"] for _ in range(len(analyse_data))]

    deal_item = list()
    for i in range(len(analyse_data)):
        item = {
            "id": i + 1,
            "name": analyse_labels[i],
            "score": analyse_data[i],
            "question": question[i],
            "advice": advice[i]
        }
        deal_item.append(item)

    pdftool = ToolPdf.toolPdf(name, deal_item)
    run_tool = threading.Thread(target=pdftool.run)
    run_tool.start()

    file_name = rf"pdfResult\{name}.pdf"

    with open(file_name, 'rb') as fh:
        response = HttpResponse(fh.read(), content_type="application/pdf")
        response['Content-Disposition'] = 'attachment; filename="{}"'.format(os.path.basename(file_name))
        return response


@login_required(login_url='login')
def TurnToWorkSpace(request):
    page_name = 'work-index.html'
    context = {}
    page = render(request=request, template_name=page_name, context=context)
    return page


@login_required(login_url='login')
def WorkSpaceFAQ(request):
    page_name = 'work-faq.html'
    context = {}
    page = render(request=request, template_name=page_name, context=context)

    return page


@login_required(login_url='login')
def WorkSpaceContact(request):
    page_name = "work-contact.html"
    context = {}
    page = render(request=request, template_name=page_name, context=context)

    return page


def WorkSpaceRegister(request):
    page_name = 'work-register.html'
    context = {}
    if request.method == "POST":
        form = RegisterForm(request.POST)
        print(form)
        print('done')
        if form.is_valid():
            form.save()
            return redirect('login')
    else:
        form = RegisterForm()
    context['form'] = form
    page = render(request=request, template_name=page_name, context=context)
    return page


def SaveToPHQ9(request):
    name = request.POST.get('name', '')
    age = request.POST.get('age', 0)
    gender = request.POST.get('gender', '')
    province_id = request.POST.get('province', '')
    city = request.POST.get('city', '')
    question1 = request.POST.get('question1', 0)
    question2 = request.POST.get('question2', 0)
    question3 = request.POST.get('question3', 0)
    question4 = request.POST.get('question4', 0)
    question5 = request.POST.get('question5', 0)
    question6 = request.POST.get('question6', 0)
    question7 = request.POST.get('question7', 0)
    question8 = request.POST.get('question8', 0)
    question9 = request.POST.get('question9', 0)

    user_instance = User.objects.get(id=request.user.id)
    phq9_records = user_instance.PHQ9Load.all()
    count = len(phq9_records)

    province_name = ProvinceLoader.Province[int(province_id)][1]

    item_load = list()
    file_path = rf"pdfResult\{request.user}-{count}-{name}.pdf"
    file_name = f"{request.user}-{count}-{name}"
    questions_item = phq9.question
    questions_scores = [int(request.POST.get(f'question{i + 1}', 0)) for i in range(9)]
    total_score = sum(questions_scores)
    result = phq9.score[total_score // 5]
    result["score"] = total_score
    result["name"] = "总评"
    item_load.append(result)

    for i in range(len(questions_item)):
        item = {
            "id": i + 1,
            "name": f'问题{i}',
            "score": questions_scores[i],
            "question": questions_item[i],
            "advice": []
        }

        item_load.append(item)

    print(item_load)

    pdftool = ToolPdf.toolPdf(file_name, item_load)
    run_tool = threading.Thread(target=pdftool.run)
    run_tool.start()

    phq9_entry = PHQ9Load(
        user=request.user,  #
        name=name,
        age=age,
        gender=gender,
        province=province_name,
        city=city,
        question1=question1,
        question2=question2,
        question3=question3,
        question4=question4,
        question5=question5,
        question6=question6,
        question7=question7,
        question8=question8,
        question9=question9,
        count=count,
        file_path=file_path,
    )
    phq9_entry.save()


@login_required(login_url='login')
def WorkNormalPHQ9Test(request):
    page_name = "work-normalPHQ-9.html"
    context = {}

    if request.method == "POST":
        SaveToPHQ9(request)
        return redirect('work-index')  # 跳转到成功页面

    context['province'] = ProvinceLoader.Province
    context["questions"] = phq9.questions

    page = render(request=request, template_name=page_name, context=context)
    return page


def selectProvince(request):
    if request.method == "POST":
        nid = request.POST.get('province_id', 0)
        try:
            city_log = ProvinceLoader.City[int(nid)]
            if city_log:
                return JsonResponse({'cityLog': city_log})
        except KeyError:
            pass


def TurnSex(item: str):
    turn_item = ""
    if item == 'Male':
        turn_item = "男"
    elif item == "Female":
        turn_item = "女"
    else:
        turn_item = "私密"
    return turn_item


@login_required(login_url='login')
def WorkShowData(request):
    page_name = "work-showData.html"
    context = dict()

    records = []
    logger = PHQ9Load.objects.filter(user=request.user)
    # print(logger)
    for obj in logger:
        # 计算总分
        total = sum(getattr(obj, f'question{i}') for i in range(1, 10))
        # 判断抑郁程度
        if total < 4:
            severity = ('无', 'severity-0')
        elif total < 10:
            severity = ('轻度', 'severity-1')
        elif total < 15:
            severity = ('中度', 'severity-2')
        elif total < 20:
            severity = ('中重度', 'severity-3')
        else:
            severity = ('重度', 'severity-4')

        # 构建问题答案列表
        answers = [int(getattr(obj, f'question{i}')) for i in range(1, 10)]
        gender = TurnSex(obj.get_gender_display())
        print(obj.name)

        records.append({
            'user': obj.name,
            'age': obj.age,
            'gender': gender,
            'province': obj.province,
            'city': obj.city,
            'created_at': obj.created_at,
            'total_score': total,
            'severity_text': severity[0],
            'severity_class': severity[1],
            'answers': answers,
            'download_url': obj.file_path
        })

    context["records"] = records
    page = render(request=request, template_name=page_name, context=context)
    return page


@login_required(login_url='login')
def Download_Path(request, file_name):
    with open(file_name, 'rb') as fh:
        response = HttpResponse(fh.read(), content_type="application/pdf")
        response['Content-Disposition'] = 'attachment; filename="{}"'.format(os.path.basename(file_name))
        return response


@login_required(login_url='login')
def WorkLLM(request):
    page_name = 'work-normalchat.html'
    context = {}
    session_keys = {
        'chat': 'chat_history',
        'column': 'column_history'
    }

    def init_chat_session():
        if session_keys['chat'] not in request.session:
            request.session[session_keys['chat']] = []
        if session_keys['column'] not in request.session:
            request.session[session_keys['column']] = []

        request.session.save()

    def save_chat_record(role, content):
        record = {'role': role, 'content': content}
        request.session[session_keys['chat']].append(record)
        request.session.save()

    init_chat_session()

    if request.method == 'POST':
        if 'reset' in request.POST:
            request.session[session_keys['chat']] = []
            request.session.save()
            return render(request, page_name, {'chat_history': []})

        def event_stream():
            user_message = request.POST.get('message', '').strip()
            if not user_message:
                yield json.dumps({"error": "消息不能为空"}) + "\n"
                return

            save_chat_record('user', user_message)
            current_chat_history = request.session[session_keys['chat']].copy()

            full_content = []
            try:
                for chunk in ColumnAi.buildResponse(current_chat_history.copy()):
                    if chunk == "[END]":
                        break
                    full_content.append(chunk)
                    yield json.dumps({
                        "content": chunk,
                        "finished": False
                    }) + "\n"

                if full_content:
                    ai_response = ''.join(full_content)
                    save_chat_record('assistant', ai_response)
                yield json.dumps({"finished": True}) + "\n"
            finally:
                pass

        return StreamingHttpResponse(event_stream(), content_type='text/event-stream')

    chat_history = request.session.get(session_keys['chat'], [])
    context['chat_history'] = chat_history
    return render(request=request, template_name=page_name, context=context)


def Create_LLMPHQ9_Pdf(request, llm_result):
    user_instance = User.objects.get(id=request.user.id)
    phq9_records = user_instance.PHQ9Load.all()
    count = len(phq9_records)

    item_load = list()
    name = user_instance.username + str(time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()))

    file_path = rf"pdfResult\{request.user}-{count}-{name}.pdf"
    file_name = f"{request.user}-{count}-{name}"
    questions_item = phq9.question

    questions_scores = llm_result
    total_score = sum(questions_scores)
    result = phq9.score[total_score // 5]

    result["score"] = total_score
    result["name"] = "总评"
    item_load.append(result)

    for i in range(len(questions_item)):
        item = {
            "id": i + 1,
            "name": f'问题{i}',
            "score": questions_scores[i],
            "question": questions_item[i],
            "advice": []
        }

        item_load.append(item)

    print(item_load)

    pdftool = ToolPdf.toolPdf(file_name, item_load)
    run_tool = threading.Thread(target=pdftool.run)
    run_tool.start()

    age = 0
    gender = "S"
    city = "None"
    province_name = "None"

    phq9_entry = PHQ9Load(
        user=request.user,  #
        name=name,
        age=age,
        gender=gender,
        province=province_name,
        city=city,
        question1=llm_result[0],
        question2=llm_result[1],
        question3=llm_result[2],
        question4=llm_result[3],
        question5=llm_result[4],
        question6=llm_result[5],
        question7=llm_result[6],
        question8=llm_result[7],
        question9=llm_result[8],
        count=count,
        file_path=file_path,
    )
    phq9_entry.save()


@login_required(login_url='login')
def WorkLLM_PHQ9(request):
    page_name = 'work-llmPHQ-9.html'
    context = {}

    session_keys = {
        'chat': 'phq9_chat_history',
        'column': 'phq9_column_history',
        'question': 'phq9_question_history',
        'out_question_id': 'out_question_id',
        'score': 'score',
        'complete': 'complete_key'
    }

    def init_chat_session():
        if session_keys['chat'] not in request.session:
            request.session[session_keys['chat']] = [{
                'role': "assistant",
                'content': '您好，欢迎来到小帕树洞, 输入开始测评进行测评'
            }]
        if session_keys['column'] not in request.session:
            request.session[session_keys['column']] = []
        if session_keys['question'] not in request.session:
            request.session[session_keys['question']] = [None] * 9
        if session_keys['out_question_id'] not in request.session:
            request.session[session_keys['out_question_id']] = -1
        request.session.save()

    def save_chat_record(role, content):
        record = {'role': role, 'content': content}
        request.session[session_keys['chat']].append(record)
        request.session.save()

    def save_question_record(question_id, score):
        if score >= 0:
            request.session[session_keys['question']][question_id] = score
        request.session.save()

    def save_out_question_id(question_id):
        request.session[session_keys['out_question_id']] = question_id
        request.session.save()

    def get_score():
        complete_key = False

        if None not in request.session[session_keys['question']]:
            complete_key = True

        return complete_key




    init_chat_session()

    if request.method == 'POST':
        if 'reset' in request.POST:
            request.session[session_keys['chat']] = [{
                'role': "assistant",
                'content': '您好，欢迎来到小帕树洞, 输入开始测评进行测评'
            }]
            request.session[session_keys['question']] = [None] * 9
            request.session[session_keys['out_question_id']] = -1
            request.session[session_keys['complete']] = False

            request.session.save()
            return render(request, page_name, {'chat_history': [{
                'role': "assistant",
                'content': '您好，欢迎来到小帕树洞, 输入开始测评进行测评'
            }]})

        def event_stream():
            user_message = request.POST.get('message', '').strip()
            if not user_message:
                yield json.dumps({"error": "消息不能为空"}) + "\n"
                return

            save_chat_record('user', user_message)

            current_chat_history = request.session[session_keys['chat']].copy()
            log_question = request.session[session_keys['question']].copy()
            out_question_id = request.session[session_keys['out_question_id']]

            full_content = []
            try:
                for chunk in ColumnAi.buildResponsePHQ9(current_chat_history.copy(),
                                                        log_question.copy(),
                                                        out_question_id):
                    if chunk == "[END]":
                        break
                    full_content.append(chunk)
                    yield json.dumps({
                        "content": chunk,
                        "finished": False
                    }) + "\n"

                if full_content:
                    ai_response = ''.join(full_content)
                    save_chat_record('assistant', ai_response)
                    session_item = ColumnAi.backToQuestion()

                    if session_item["out_question"]:
                        save_out_question_id(session_item["out_question_id"])
                    if session_item["score"] != -1:
                        save_question_record(session_item["score_id"], session_item["score"])


                    if get_score():
                        Create_LLMPHQ9_Pdf(request, request.session[session_keys['question']])
                        yield json.dumps({"finished": True, "content": "over", "phq9_complete": 1}) + "\n"
                    else:
                        yield json.dumps({"finished": True, "phq9_complete": 0}) + "\n"
            finally:
                pass

        return StreamingHttpResponse(event_stream(), content_type='text/event-stream')

    chat_history = request.session.get(session_keys['chat'], [])
    context['chat_history'] = chat_history

    page = render(request=request, template_name=page_name, context=context)
    return page
